﻿using Newtonsoft.Json;
using QDPay.Bus.domain.pay;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;

namespace QDPay.Test
{
    public class FaceSDK
    {
        // 声明
        [DllImport("SDK\\x64\\lib\\WxpayFaceSDK.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public extern static int wxpayCallFaceService(IntPtr reqBuf, UInt32 reqSize, out IntPtr pRespBuf, out UInt32 pRespSize);

        [DllImport("SDK\\x64\\lib\\WxpayFaceSDK.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
        public extern static int wxpayReleaseResponse(out IntPtr pRespBuf);

        // 封装
        public static int CallWxpayFaceService(string req, ref string resp)
        {
            byte[] reqBuf = Encoding.UTF8.GetBytes(req);
            IntPtr reqPtr = Marshal.AllocHGlobal(reqBuf.Length);
            Marshal.Copy(reqBuf, 0, reqPtr, reqBuf.Length);

            IntPtr respPtr;
            UInt32 respSize;

            int ret = wxpayCallFaceService(reqPtr, (UInt32)reqBuf.Length, out respPtr, out respSize);
            if (ret == 0)
            {
                byte[] respBuf = new byte[respSize];
                Marshal.Copy(respPtr, respBuf, 0, (int)respSize);
                resp = Encoding.UTF8.GetString(respBuf);
                wxpayReleaseResponse(out respPtr);
            }
            Marshal.FreeHGlobal(reqPtr);
            return ret;
        }

        public static string CallService(string cmd)
        {
            var now = GetTimeStamp();
            string req = "{\"cmd\":\"" + cmd + "\",\"version\":\"1\",\"now\":" + now + "}";
            string resp = "";
            var ret = CallWxpayFaceService(req, ref resp);
            return resp;
        }

        public static string GetRawData()
        {
            var rawData = string.Empty;
            var initJson = CallService("initWxpayface");

            if (initJson.ToUpper().Contains("SUCCESS"))
            {
                var rawJson = CallService("getWxpayfaceRawdata");
                Regex r = new Regex("rawdata\":\"([\\s\\S]+?)\"");
                if (r.IsMatch(rawJson))
                    rawData = r.Match(rawJson).Groups[1].Value;
            }
            CallService("releaseWxpayface");
            return rawData;
        }

        public static string GetFaceCode(FaceCodeInput model)
        {
            var sb = new StringBuilder();
            sb.Append("{");
            sb.Append("\"cmd\":\"getWxpayfaceCode\",");
            sb.AppendFormat("\"now\":{0},", GetTimeStamp());
            sb.AppendFormat("\"version\":\"{0}\",", "1");
            sb.AppendFormat("\"appid\":\"{0}\",", model.appid);
            sb.AppendFormat("\"mch_id\":\"{0}\",", model.mch_id);
            sb.AppendFormat("\"sub_appid\":\"{0}\",", model.sub_appid);
            sb.AppendFormat("\"sub_mch_id\":\"{0}\",", model.sub_mch_id);
            sb.AppendFormat("\"store_id\":\"{0}\",", model.store_id);
            sb.AppendFormat("\"face_authtype\":\"{0}\",", model.face_authtype);
            sb.AppendFormat("\"authinfo\":\"{0}\",", model.authinfo);
            sb.AppendFormat("\"out_trade_no\":\"{0}\",", model.out_trade_no);
            sb.AppendFormat("\"total_fee\":\"{0}\",", model.total_fee);
            sb.AppendFormat("\"telephone\":\"{0}\"", model.telephone);
            sb.Append("}");
            string resp = "";
            var ret = CallWxpayFaceService(sb.ToString(), ref resp);
            return resp;
        }

        private static int GetTimeStamp()
        {
            var utcNow = DateTime.Now;
            var timeSpan = utcNow - new DateTime(1970, 1, 1, 8, 0, 0);
            return (int)timeSpan.TotalSeconds;
        }

    }
}